package com.magicstone.common;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import net.sf.jxls.exception.ParsePropertyException;
import net.sf.jxls.transformer.XLSTransformer;

public class WordHelper {
	private final static Logger logger = LogManager.getLogger(WordHelper.class);
	public static String TEMP = "template.xlsx";
	private static WordHelper _helper = null;
	public static final int MAX_ROWS = 10000;
	public static final String EXTENSION = "xlsx";
	private static Configuration _configuration = null;
	
	private WordHelper(){
		
	}
	
	public static WordHelper getInstance(){
		if(null == _helper){
	        _configuration = new Configuration();  
	        _configuration.setDefaultEncoding("UTF-8");  
			_helper = new WordHelper();
		}
		return _helper;
	}
	
	public static String generateName(String ext){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssS");
		String nowTime = sdf.format(new Date());
		return nowTime + ext;
	}
	
	public String pathFix(String path){
		String pathFixed = path;
		int index = path.indexOf("WEB-INF");
		if(-1 == index){
			pathFixed = path + (path.endsWith("\\") ? "WEB-INF\\classes" : "\\WEB-INF\\classes");
			logger.debug("Path pre-fixed:" + path);
		}
		
		return pathFixed;
	}
	
	public String generateWord(String fromRoot, String from, String toRoot, String to, Map beans) {
		logger.debug(from + ":" + to);
		mkDir(new File(toRoot));
		String result = "";
		Template t = null;
		try {
			_configuration.setDirectoryForTemplateLoading(new File(fromRoot));
			t = _configuration.getTemplate(from); // 文件名
		} catch (IOException e) {
			logger.error(e.getMessage());
			return result;
		}
		Writer out = null;
		String toName = "";
		try {
			toName = toRoot + (toRoot.endsWith("/") || toRoot.endsWith("\\") ? to : "/" + to);
			logger.debug(toName);
			File outStream = new File(toName);
			out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outStream)));
		} catch (FileNotFoundException e) {
			logger.error(e.getMessage());
			return result;
		}

		try {
			t.process(beans, out);
			result = toName;
		} catch (TemplateException e) {
			logger.error(e.getMessage());
			return result;
		} catch (IOException e) {
			logger.error(e.getMessage());
			return result;
		}

		return result;
	}
	
	public static String getCurrentDir(){
		File dir = new File(".");
		return dir.getAbsolutePath();
	}
	
	public static String getAppRoot(){
		String path = "";
		File directory  = new File(".");
        try {
			path = directory.getCanonicalPath();
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
        return path;
	}
	/*
	 * Load jxls template file from resource.
	 */
	public boolean loadTemplate(String dest){
		boolean result = false;
		try {
			InputStream is = this.getClass().getResourceAsStream("/jxls.xlsx");
				if(null != is){
				File desFile = new File(dest);
				mkDir(desFile.getAbsoluteFile().getParentFile());
				desFile.createNewFile();
				FileOutputStream fos = new FileOutputStream(desFile);
				int bytesRead;
				byte[] buf = new byte[4 * 1024]; // 4K buffer
				while ((bytesRead = is.read(buf)) != -1) {
					fos.write(buf, 0, bytesRead);
				}
				fos.flush();
				fos.close();
				is.close();
				result = true;
			}else{
				logger.debug("Fail to read template!");
			}
		} catch (IOException e) {
			logger.debug(e.getMessage());
		}
		return result;
	}
	
	public static boolean mkDir(File file) {
		file = file.getAbsoluteFile();
		boolean result = false;
		if(null != file){
			logger.debug(file.getAbsolutePath());
			File parent = file.getParentFile();
			if(null != parent){
				if (parent.exists()) {
					file.mkdir();
					result = true;
					logger.debug("create " + file.getAbsolutePath());
				} else {
					if(mkDir(parent)){
						file.mkdir();
						result = true;
						logger.debug("create " + file.getAbsolutePath());
					}
				}
			}else{
				logger.debug(file.getAbsolutePath() + ":" + file.getParent());
			}
		}
		return result;
	}
	
	public String generateWord4Web(ServletContext sc, String from, Map beans){
		String result = "";
		WordHelper helper = WordHelper.getInstance();
		String root = helper.pathFix(sc.getRealPath("/"));

		logger.debug(root);
		
		String fromRoot = root + "\\word\\";
		String toRoot = root + "\\word\\temp\\";
		String to = WordHelper.generateName(".doc");// 要生成的文件
		result = helper.generateWord(fromRoot, from, toRoot, to, beans);
		logger.debug("Context path:" + sc.getContextPath());

		logger.debug("Template name:" + fromRoot + from);
		logger.debug("Temporary excel file:" + toRoot + to);
		return result;
	}

}
